aarch32: Implement errata workarounds for Cortex A57
authorDimitris Papastamos <dimitris.papastamos@arm.com>
Mon, 5 Jun 2017 13:55:41 +0000 (14:55 +0100)
committerDimitris Papastamos <dimitris.papastamos@arm.com>
Tue, 20 Jun 2017 14:14:01 +0000 (15:14 +0100)
This brings the implementation on par with the software
errata workarounds for AArch64.

Change-Id: I98a85fd92e32ae4259f4ec5b3e93cffc87090064
Signed-off-by: Dimitris Papastamos <dimitris.papastamos@arm.com>
lib/cpus/aarch32/cortex_a57.S

index ed478463721683b928d5e10dfb413ce182c9a124..a791e4ee979e3e8cad07530b614fecb52db145f4 100644 (file)
@@ -50,11 +50,312 @@ func cortex_a57_disable_ext_debug
        bx      lr
 endfunc cortex_a57_disable_ext_debug
 
+       /* --------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #806969.
+        * This applies only to revision r0p0 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * --------------------------------------------------
+        */
+func errata_a57_806969_wa
+       /*
+        * Compare r0 against revision r0p0
+        */
+       mov             r2, lr
+       bl              check_errata_806969
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_NO_ALLOC_WBWA
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx      lr
+endfunc errata_a57_806969_wa
+
+func check_errata_806969
+       mov     r1, #0x00
+       b       cpu_rev_var_ls
+endfunc check_errata_806969
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #813419.
+        * This applies only to revision r0p0 of Cortex A57.
+        * ---------------------------------------------------
+        */
+func check_errata_813419
+       /*
+        * Even though this is only needed for revision r0p0, it
+        * is always applied due to limitations of the current
+        * errata framework.
+        */
+       mov     r0, #ERRATA_APPLIES
+       bx      lr
+endfunc check_errata_813419
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #813420.
+        * This applies only to revision r0p0 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------
+        */
+func errata_a57_813420_wa
+       /*
+        * Compare r0 against revision r0p0
+        */
+       mov             r2, lr
+       bl              check_errata_813420
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_DCC_AS_DCCI
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc errata_a57_813420_wa
+
+func check_errata_813420
+       mov     r1, #0x00
+       b       cpu_rev_var_ls
+endfunc check_errata_813420
+
+       /* --------------------------------------------------------------------
+        * Disable the over-read from the LDNP instruction.
+        *
+        * This applies to all revisions <= r1p2. The performance degradation
+        * observed with LDNP/STNP has been fixed on r1p3 and onwards.
+        *
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------------------------
+        */
+func a57_disable_ldnp_overread
+       /*
+        * Compare r0 against revision r1p2
+        */
+       mov             r2, lr
+       bl              check_errata_disable_ldnp_overread
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_DIS_OVERREAD
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc a57_disable_ldnp_overread
+
+func check_errata_disable_ldnp_overread
+       mov     r1, #0x12
+       b       cpu_rev_var_ls
+endfunc check_errata_disable_ldnp_overread
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #826974.
+        * This applies only to revision <= r1p1 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------
+        */
+func errata_a57_826974_wa
+       /*
+        * Compare r0 against revision r1p1
+        */
+       mov             r2, lr
+       bl              check_errata_826974
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_DIS_LOAD_PASS_DMB
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc errata_a57_826974_wa
+
+func check_errata_826974
+       mov     r1, #0x11
+       b       cpu_rev_var_ls
+endfunc check_errata_826974
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #826977.
+        * This applies only to revision <= r1p1 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------
+        */
+func errata_a57_826977_wa
+       /*
+        * Compare r0 against revision r1p1
+        */
+       mov             r2, lr
+       bl              check_errata_826977
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_GRE_NGRE_AS_NGNRE
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc errata_a57_826977_wa
+
+func check_errata_826977
+       mov     r1, #0x11
+       b       cpu_rev_var_ls
+endfunc check_errata_826977
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #828024.
+        * This applies only to revision <= r1p1 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------
+        */
+func errata_a57_828024_wa
+       /*
+        * Compare r0 against revision r1p1
+        */
+       mov             r2, lr
+       bl              check_errata_828024
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       /*
+        * Setting the relevant bits in CORTEX_A57_ACTLR has to be done in 2
+        * instructions here because the resulting bitmask doesn't fit in a
+        * 16-bit value so it cannot be encoded in a single instruction.
+        */
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_NO_ALLOC_WBWA
+       orr64_imm       r0, r1, (CORTEX_A57_ACTLR_DIS_L1_STREAMING | CORTEX_A57_ACTLR_DIS_STREAMING)
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc errata_a57_828024_wa
+
+func check_errata_828024
+       mov     r1, #0x11
+       b       cpu_rev_var_ls
+endfunc check_errata_828024
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #829520.
+        * This applies only to revision <= r1p2 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------
+        */
+func errata_a57_829520_wa
+       /*
+        * Compare r0 against revision r1p2
+        */
+       mov             r2, lr
+       bl              check_errata_829520
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r0, r1, CORTEX_A57_ACTLR_DIS_INDIRECT_PREDICTOR
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc errata_a57_829520_wa
+
+func check_errata_829520
+       mov     r1, #0x12
+       b       cpu_rev_var_ls
+endfunc check_errata_829520
+
+       /* ---------------------------------------------------
+        * Errata Workaround for Cortex A57 Errata #833471.
+        * This applies only to revision <= r1p2 of Cortex A57.
+        * Inputs:
+        * r0: variant[4:7] and revision[0:3] of current cpu.
+        * Shall clobber: r0-r3
+        * ---------------------------------------------------
+        */
+func errata_a57_833471_wa
+       /*
+        * Compare r0 against revision r1p2
+        */
+       mov             r2, lr
+       bl              check_errata_833471
+       mov             lr, r2
+       cmp             r0, #ERRATA_NOT_APPLIES
+       beq             1f
+       ldcopr16        r0, r1, CORTEX_A57_ACTLR
+       orr64_imm       r1, r1, CORTEX_A57_ACTLR_FORCE_FPSCR_FLUSH
+       stcopr16        r0, r1, CORTEX_A57_ACTLR
+1:
+       bx              lr
+endfunc errata_a57_833471_wa
+
+func check_errata_833471
+       mov     r1, #0x12
+       b       cpu_rev_var_ls
+endfunc check_errata_833471
+
        /* -------------------------------------------------
         * The CPU Ops reset function for Cortex-A57.
+        * Shall clobber: r0-r6
         * -------------------------------------------------
         */
 func cortex_a57_reset_func
+       mov     r5, lr
+       bl      cpu_get_rev_var
+       mov     r4, r0
+
+#if ERRATA_A57_806969
+       mov     r0, r4
+       bl      errata_a57_806969_wa
+#endif
+
+#if ERRATA_A57_813420
+       mov     r0, r4
+       bl      errata_a57_813420_wa
+#endif
+
+#if A57_DISABLE_NON_TEMPORAL_HINT
+       mov     r0, r4
+       bl      a57_disable_ldnp_overread
+#endif
+
+#if ERRATA_A57_826974
+       mov     r0, r4
+       bl      errata_a57_826974_wa
+#endif
+
+#if ERRATA_A57_826977
+       mov     r0, r4
+       bl      errata_a57_826977_wa
+#endif
+
+#if ERRATA_A57_828024
+       mov     r0, r4
+       bl      errata_a57_828024_wa
+#endif
+
+#if ERRATA_A57_829520
+       mov     r0, r4
+       bl      errata_a57_829520_wa
+#endif
+
+#if ERRATA_A57_833471
+       mov     r0, r4
+       bl      errata_a57_833471_wa
+#endif
+
        /* ---------------------------------------------
         * Enable the SMP bit.
         * ---------------------------------------------
@@ -63,7 +364,7 @@ func cortex_a57_reset_func
        orr64_imm       r0, r1, CORTEX_A57_ECTLR_SMP_BIT
        stcopr16        r0, r1, CORTEX_A57_ECTLR
        isb
-       bx      lr
+       bx      r5
 endfunc cortex_a57_reset_func
 
        /* ----------------------------------------------------
@@ -162,6 +463,36 @@ func cortex_a57_cluster_pwr_dwn
        b       cortex_a57_disable_ext_debug
 endfunc cortex_a57_cluster_pwr_dwn
 
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A57. Must follow AAPCS.
+ */
+func cortex_a57_errata_report
+       push    {r12, lr}
+
+       bl      cpu_get_rev_var
+       mov     r4, r0
+
+       /*
+        * Report all errata. The revision-variant information is passed to
+        * checking functions of each errata.
+        */
+       report_errata ERRATA_A57_806969, cortex_a57, 806969
+       report_errata ERRATA_A57_813419, cortex_a57, 813419
+       report_errata ERRATA_A57_813420, cortex_a57, 813420
+       report_errata A57_DISABLE_NON_TEMPORAL_HINT, cortex_a57, \
+               disable_ldnp_overread
+       report_errata ERRATA_A57_826974, cortex_a57, 826974
+       report_errata ERRATA_A57_826977, cortex_a57, 826977
+       report_errata ERRATA_A57_828024, cortex_a57, 828024
+       report_errata ERRATA_A57_829520, cortex_a57, 829520
+       report_errata ERRATA_A57_833471, cortex_a57, 833471
+
+       pop     {r12, lr}
+       bx      lr
+endfunc cortex_a57_errata_report
+#endif
+
 declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
        cortex_a57_reset_func, \
        cortex_a57_core_pwr_dwn, \